使用Python获得活动窗口

您所在的位置:网站首页 python win32gui文档 使用Python获得活动窗口

使用Python获得活动窗口

2023-04-08 06:57| 来源: 网络整理| 查看: 265

感谢Nuno André的回答,他展示了如何使用ctypes与Windows APIs交互。我已经用他的提示写了一个实现的例子。

ctypes库从v2.5开始就包含在Python中,这意味着几乎每个用户都有它。而且它的界面比win32gui(截至本文写作时,最后一次更新是在2017年)这样的老旧和死亡的库要干净得多。((2020年底的更新。死去的win32gui库已经起死回生,改名为pywin32,所以如果你想要一个被维护的库,现在又是一个有效的选择。但那个库比我的代码慢6%。))

文件在这里。https://docs.python.org/3/library/ctypes.html(如果你想写你自己的代码,你必须阅读它的使用帮助,否则你会导致分段故障崩溃,嘿嘿)。

基本上,ctypes 包括对最常见的 Windows DLLs 的绑定。下面是你如何用纯 Python 检索前台窗口的标题,不需要外部库!只需要内置的 ctypes!只有内置的 ctypes!:-)

关于ctypes最酷的事情是,你可以在谷歌上看到任何 Windows API for 任何thing you need, and if you want to use it, you 可以通过ctypes来做!

Python 3 Code:

from typing import Optional from ctypes import wintypes, windll, create_unicode_buffer def getForegroundWindowTitle() -> Optional[str]: hWnd = windll.user32.GetForegroundWindow() length = windll.user32.GetWindowTextLengthW(hWnd) buf = create_unicode_buffer(length + 1) windll.user32.GetWindowTextW(hWnd, buf, length + 1) # 1-liner alternative: return buf.value if buf.value else None if buf.value: return buf.value else: return None

性能非常好。【替换代码4MILLISECONDS在我的电脑上(0.00001秒)。

在Python 2上也能工作,只需做很小的改动。如果你在Python 2上,我想你只需要删除类型注释(from typing import Optional和 -> Optional[str])。

Enjoy!

Win32技术解释。

替换代码8】的变量是长度。当前 text 在UTF-16(Windows Wide "Unicode")字符中。 (It is NOT the number of BYTES.) We have to add + 1 to add room for the null terminator at the end of C-style strings. If we don't do that, we would not have enough space in the buffer to fit the final real character of the 当前 text, and Windows would truncate the returned string (it does that to ensure that it fits the super important final string Null-terminator).

The create_unicode_buffer function allocates room for that m任何 UTF-16 CHARACTERS.

大多数(或全部?总是阅读微软的MSDN文档!)与Unicode文本有关的Windows APIs将缓冲区长度作为CHARACTERS。而不是作为字节。

还要仔细看一下函数的调用。有些以W结尾(如GetWindowTextLengthW)。这代表了 "Wide string",这是Windows对Unicode字符串的称呼。非常重要的是,你要进行这些W的调用,以获得正确的Unicode字符串(支持国际字符)。

PS:Windows使用Unicode已经有很长一段时间了。我知道一个事实,Windows 10是fullyUnicode,并且只想要W的函数调用。我不知道确切的截止日期是什么时候,旧版本的Windows使用了other多字节的字符串格式,但我认为那是在Windows Vista之前,而且谁在乎呢?旧的Windows版本(甚至是7和8.1)是死的,不受微软支持。

再次...享受!:-)

2020年底更新,基准与pywin32库对比。

import time import win32ui from typing import Optional from ctypes import wintypes, windll, create_unicode_buffer def getForegroundWindowTitle() -> Optional[str]: hWnd = windll.user32.GetForegroundWindow() length = windll.user32.GetWindowTextLengthW(hWnd) buf = create_unicode_buffer(length + 1) windll.user32.GetWindowTextW(hWnd, buf, length + 1) return buf.value if buf.value else None def getForegroundWindowTitle_Win32UI() -> Optional[str]: # WARNING: This code sometimes throws an exception saying # "win32ui.error: No window is is in the foreground." # which is total nonsense. My function doesn't fail that way. return win32ui.GetForegroundWindow().GetWindowText() iterations = 1_000_000 start_time = time.time() for x in range(iterations): foo = getForegroundWindowTitle() elapsed1 = time.time() - start_time print("Elapsed 1:", elapsed1, "seconds") start_time = time.time() for x in range(iterations): foo = getForegroundWindowTitle_Win32UI() elapsed2 = time.time() - start_time print("Elapsed 2:", elapsed2, "seconds") win32ui_pct_slower = ((elapsed2 / elapsed1) - 1) * 100 print("Win32UI library is", win32ui_pct_slower, "percent slower.")

在AMD Ryzen 3900x上进行多次运行后的典型结果。

My function: 4.5769994258880615 seconds

Win32UI库。4.8619983196258545秒

Win32UI库的速度要慢6.226762715455125%。

然而,差别很小,所以你可能想使用那个库,因为它现在又复活了(之前它从2017年起就死了)。但你将不得不处理那个库的奇怪的 "没有窗口在前台 "的异常,而我的代码并没有受到影响(见基准代码中的代码注释)。

无论哪种方式......享受吧!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3